package com.ruoyi.door.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.order.OrderNoGenerator;
import com.ruoyi.door.controller.app.baofu.vo.SinglePayReqVO;
import com.ruoyi.door.controller.app.orderinfo.vo.AppOrderDetailCreateReqVO;
import com.ruoyi.door.controller.app.orderinfo.vo.AppOrderInfoCreateReqVO;
import com.ruoyi.door.controller.app.orderinfo.vo.AppOrderInfoSubmitReqVO;
import com.ruoyi.door.domain.*;
import com.ruoyi.door.utils.HouseUtil;
import com.ruoyi.door.utils.WxTemplate;
import com.ruoyi.door.utils.baofu.BaoFuJuHeService;
import com.ruoyi.door.utils.baofu.BaoFuXieYiService;
import com.ruoyi.system.service.ISysUserService;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class DoorOrderService {
    @Autowired
    private BaoFuXieYiService baoFuXieYiService;
    @Autowired
    private EasyEntityQuery easyEntityQuery;

    @Autowired
    private BaoFuJuHeService baoFuJuHeService;
    @Autowired
    private ISysUserService sysUserService;
    @Value("${weChat.minApp.appId}")
    private String miniAppId;
    @Value("${weChat.minApp.appSecret}")
    private String miniAppSecret;

    @Value("${weChat.mp.appId}")
    private String mpAppId;
    @Value("${weChat.mp.appSecret}")
    private String mpAppSecret;
    @Autowired
    private WxTemplate wxTemplate;

    /**
     * 提交支付
     *
     * @param reqVO
     * @return
     */
    public Object submit(AppOrderInfoSubmitReqVO reqVO) {
        DoorOrder orderInfo = easyEntityQuery.queryable(DoorOrder.class)
                .where(d -> {
                    d.id().eq(reqVO.getOrderId());
                    d.orderNo().eq(reqVO.getOrderNo());
                }).firstOrNull();
        if (ObjectUtil.isNull(orderInfo)) {
            throw new ServiceException("订单信息不存在");
        }

        //微信支付
        if (orderInfo.getPayChannel().equals("1")) {
            return baoFuJuHeService.unifiedOrder("WECHAT_JSAPI",
                    mpAppId, reqVO.getOpenId(), String.valueOf(orderInfo.getType()),
                    String.valueOf(orderInfo.getTotalPrice().multiply(BigDecimal.valueOf(100)).intValue()),
                    orderInfo.getOrderNo());
        } else if (orderInfo.getPayChannel().equals("2")) {
            SysUser sysUser = sysUserService.selectUserById(orderInfo.getUserId());
            //银行卡
            SinglePayReqVO singlePayReqVO = SinglePayReqVO.builder()
                    .userId(String.valueOf(SecurityUtils.getUserId()))
                    .protocolNo(orderInfo.getProtocolNo())
                    .amount(String.valueOf(orderInfo.getTotalPrice().multiply(BigDecimal.valueOf(100)).intValue()))
                    .userName(sysUser.getUserName())
                    .email(sysUser.getEmail())
                    .phone(sysUser.getPhonenumber())
                    .nickName(sysUser.getNickName())
                    .idCard("")
                    .registerTime(sysUser.getCreateTime())
                    .registerIp(sysUser.getLoginIp())
                    .identifyState("0")
                    .payIp(IpUtils.getIpAddr())
                    .chName(orderInfo.getChName())
                    .chIdNo(orderInfo.getChIdNo())
                    .chCardNo(orderInfo.getChCardNo())
                    .chMobile(orderInfo.getChMobile())
                    .build();
            return baoFuXieYiService.singlePay(singlePayReqVO);
        } else {
            throw new ServiceException("支付渠道错误");
        }

    }

    /**
     * 支付回调
     *
     * @param orderNo 本系统订单号
     * @param tradeNo 三方系统订单号
     */
    public void payCallBack(String orderNo, String tradeNo) {
        DoorOrder orderInfo = easyEntityQuery.queryable(DoorOrder.class).where(d -> d.orderNo().eq(orderNo)).firstOrNull();
        if (ObjectUtil.isNotNull(orderInfo) && 0L == orderInfo.getOrderStatus()) {
            orderInfo.setPayTime(DateUtils.getNowDate());
            orderInfo.setOrderStatus(1L);
            orderInfo.setTradeNo(tradeNo);
            easyEntityQuery.updatable(orderInfo).executeRows();
            List<DoorOrderDetail> orderDetails = easyEntityQuery.queryable(DoorOrderDetail.class).where(d -> d.orderId().eq(orderInfo.getId())).toList();
            //运维的话更新到期时间

                for (DoorOrderDetail doorOrderDetail : orderDetails) {
                    DoorDeptPrice doorDeptPrice = easyEntityQuery.queryable(DoorDeptPrice.class).where(d -> d.deptId().eq(doorOrderDetail.getStreet())).firstOrNull();
//
                    if (ObjectUtil.isNull(doorDeptPrice)){
                        doorOrderDetail.setRemark(DateUtil.now() +",未配置赠送规则");
                        easyEntityQuery.updatable(doorOrderDetail).executeRows();

                    }else{
                        //计算到期时间
                        if (doorOrderDetail.getType() == 1L||doorOrderDetail.getType() == 4L) {
                            DoorHouse doorHouse = easyEntityQuery.queryable(DoorHouse.class).where(d -> d.id().eq(doorOrderDetail.getHouseId())).firstOrNull();
                            doorHouse.setUpdateTime(DateUtils.getNowDate());
                            BigDecimal totalPrice = doorOrderDetail.getTotalPrice();
                            //增加余额
                            int year = (int) (doorOrderDetail.getBuyCount() / 12);
                            if (year > 0) {
                                //判断是否配置了赠送
                                if (ObjectUtil.isNotNull(doorDeptPrice) && doorDeptPrice.getGiftMonthOfByOneYear() > 0) {
                                    BigDecimal giftMonthOfByOneYear = BigDecimal.valueOf(doorDeptPrice.getGiftMonthOfByOneYear()).multiply(BigDecimal.valueOf(year));
                                    BigDecimal multiply = doorHouse.getMonthPrice().multiply(giftMonthOfByOneYear);
                                    doorHouse.setRemark(DateUtil.now() + ",赠送" + multiply + "元");
                                    doorOrderDetail.setRemark(DateUtil.now() + ",赠送" + multiply + "元");
                                    totalPrice = totalPrice.add(multiply);
                                    easyEntityQuery.updatable(doorOrderDetail).executeRows();

                                }
                            }
                            doorHouse.setBalance(doorHouse.getBalance().add(totalPrice));
                            //计算到期时间

                            doorHouse.setEndDate(HouseUtil.calculateEndDateFromBaseDate(doorHouse.getBalance(), doorHouse.getMonthPrice()));
                            doorHouse.setStartDate(new DateTime(LocalDate.of(DateUtil.thisYear(), DateUtil.thisMonth()+1, 1)));

                            easyEntityQuery.updatable(doorHouse).executeRows();
                        }
                    }

                    //发送模板消息
                    if (StrUtil.isNotEmpty(orderInfo.getOpenid())) {
                        if (1L == doorOrderDetail.getType()||4L == doorOrderDetail.getType()) {
                            wxTemplate.yunWeiFei(orderInfo.getOrderNo(), orderInfo.getOpenid(), orderDetails.get(0).getDoor(), orderDetails.get(0).getAddress(), orderDetails.get(0).getPhone(), String.valueOf(orderInfo.getTotalPrice()));
                        }
                        if (2L == doorOrderDetail.getType()) {
                            //买卡
                            wxTemplate.menJinKa(orderInfo.getOrderNo(), orderInfo.getOpenid(), orderDetails.get(0).getAddress(), orderDetails.get(0).getPhone(), String.valueOf(orderDetails.size()), String.valueOf(orderInfo.getTotalPrice()));
                        }
                        if (3L == doorOrderDetail.getType()) {
//                            DoorPlan doorPlan = easyEntityQuery.queryable(DoorPlan.class)
//                                    .where(d -> {
//                                        d.price().eq(orderDetails.get(0).getUnitPrice());
//                                        d.id().eq(orderDetails.get(0).getPlanId());
//                                    }).firstOrNull();
                            //人脸
                                log.info("支付回调：{}，订单号：{}，发送人脸消息！", "payCallBack", orderInfo.getOrderNo());
                                wxTemplate.renLian(orderInfo.getOrderNo(), orderInfo.getOpenid(), orderDetails.get(0).getAddress(), orderDetails.get(0).getPhone(), "门禁卡", String.valueOf(orderInfo.getTotalPrice()));

                        }
                    }
                }
        }
    }

    /**
     * 创建订单
     *
     * @param reqVO
     * @return
     */
    @Transactional
    public DoorOrder add(AppOrderInfoCreateReqVO reqVO) {
        if (CollectionUtil.isEmpty(reqVO.getOrderDetailList())) {
            throw new ServiceException("订单信息不能为空");
        }
        DoorOrder orderInfo = BeanUtil.toBean(reqVO, DoorOrder.class);
        List<DoorOrderDetail> orderDetails = new ArrayList<>();
        for (AppOrderDetailCreateReqVO orderDetailReq : reqVO.getOrderDetailList()) {
            DoorOrderDetail orderDetail = BeanUtil.toBean(orderDetailReq, DoorOrderDetail.class);
            orderDetail.setCreateTime(DateUtils.getNowDate());
            if (reqVO.getType() == 1L&&reqVO.getPayChannel().equals("2")&&reqVO.getOrderDetailList().size()==1) {
                orderDetail.setUserId(SecurityUtils.getUserId());
            }
            if (orderDetail.getType() == 1L) {
                //运维费
                DoorHouse doorHouse = easyEntityQuery.queryable(DoorHouse.class).where(d -> d.id().eq(orderDetail.getHouseId())).firstOrNull();
                orderDetail.setUnitPrice(doorHouse.getMonthPrice());
                orderDetail.setBuyCount(orderDetailReq.getBuyCount());
                orderDetail.setTotalPrice(doorHouse.getMonthPrice().multiply(BigDecimal.valueOf(orderDetail.getBuyCount())));
            } else if (reqVO.getType() == 2L) {
                //安装费
                DoorDeptPrice doorDeptPrice = easyEntityQuery.queryable(DoorDeptPrice.class).where(d -> {
                    d.deptId().eq(orderDetail.getStreet());
                }).firstOrNull();
                if (ObjectUtil.isNull(doorDeptPrice)) {
                    throw new ServiceException("价格信息不存在");
                }
                
                BigDecimal installPrice;
                if (StrUtil.isNotEmpty(orderDetailReq.getInstallPriceName())) {
                    // 从installPrice JSON数组中根据名称查找价格
                    installPrice = findPriceByName(doorDeptPrice.getInstallPrice(), orderDetailReq.getInstallPriceName());
                    if (installPrice == null) {
                        throw new ServiceException("未找到指定名称的安装价格：" + orderDetailReq.getInstallPriceName());
                    }
                } else {
                    // 兼容原有逻辑，如果没有传installPriceName，则使用原来的getInstallPrice()方法
                    // 注意：这里可能需要根据实际业务调整，因为getInstallPrice()返回的是String类型
                    throw new ServiceException("安装费订单必须传入installPriceName参数");
                }
                
                orderDetail.setBuyCount(orderDetailReq.getBuyCount());
                orderDetail.setUnitPrice(installPrice);
                orderDetail.setTotalPrice(installPrice.multiply(BigDecimal.valueOf(orderDetail.getBuyCount())));
            } else if (reqVO.getType() == 3L) {
                if (orderDetail.getIsPolice() .equals( "1")) {
                    orderDetail.setBuyCount(orderDetailReq.getBuyCount());
                    orderDetail.setUnitPrice(orderDetailReq.getEngineeringFee());
                    orderDetail.setTotalPrice(orderDetailReq.getEngineeringFee());
                }else{
                    DoorDeptPrice doorDeptPrice = easyEntityQuery.queryable(DoorDeptPrice.class).where(d -> {
                        d.deptId().eq(orderDetail.getStreet());
                    }).firstOrNull();
                    if (ObjectUtil.isNull(doorDeptPrice)) {
                        throw new ServiceException("价格信息不存在");
                    }
                    orderDetail.setBuyCount(orderDetailReq.getBuyCount());
                    orderDetail.setUnitPrice(doorDeptPrice.getCardPrice());
                    orderDetail.setTotalPrice(doorDeptPrice.getCardPrice().multiply(BigDecimal.valueOf(orderDetail.getBuyCount())));
                }


            }
            //人脸
            /**
             isPolice=1; 单价unitPrice=1;工程金额=buyCount=11
             isPolice=0; 单价unitPrice=paln的金额;会校验数据库
             */
            else if (reqVO.getType() == 4L) {
                if (orderDetailReq.getIsPolice().equals("1")){
                    orderDetail.setBuyCount(1L);
                    orderDetail.setUnitPrice(orderDetailReq.getProjectPrice());
                    orderDetail.setTotalPrice(orderDetailReq.getProjectPrice());
                }else{
                    //安装费+运维费
                    DoorHouse doorHouse = easyEntityQuery.queryable(DoorHouse.class).where(d -> d.id().eq(orderDetail.getHouseId())).firstOrNull();
                    DoorDeptPrice doorDeptPrice = easyEntityQuery.queryable(DoorDeptPrice.class).where(d -> {
                        d.deptId().eq(orderDetail.getStreet());
                    }).firstOrNull();
                    if (ObjectUtil.isNull(doorDeptPrice)) {
                        throw new ServiceException("价格信息不存在");
                    }

                    BigDecimal installPrice;
                    if (StrUtil.isNotEmpty(orderDetailReq.getInstallPriceName())) {
                        // 从installPrice JSON数组中根据名称查找价格
                        installPrice = findPriceByName(doorDeptPrice.getInstallPrice(), orderDetailReq.getInstallPriceName());
                        if (installPrice == null) {
                            throw new ServiceException("未找到指定名称的安装价格：" + orderDetailReq.getInstallPriceName());
                        }
                    } else {
                        // 兼容原有逻辑，如果没有传installPriceName，则使用原来的getInstallPrice()方法
                        // 注意：这里可能需要根据实际业务调整，因为getInstallPrice()返回的是String类型
                        throw new ServiceException("安装费+运维费订单必须传入installPriceName参数");
                    }

                    orderDetail.setBuyCount(orderDetailReq.getBuyCount());
                    orderDetail.setUnitPrice(doorHouse.getMonthPrice());
                    orderDetail.setTotalPrice(orderDetail.getUnitPrice().multiply(BigDecimal.valueOf(orderDetail.getBuyCount()))
                            .add(installPrice));
                }



            } else {
                throw new ServiceException("订单类型错误");
            }
            orderDetails.add(orderDetail);
        }

        //如果是运维费;需要可以查看用户订单信息
        if (reqVO.getType() == 1L&&reqVO.getPayChannel().equals("2")&&reqVO.getOrderDetailList().size()==1) {
            orderInfo.setUserId(SecurityUtils.getUserId());
        }
        orderInfo.setOrderNo(OrderNoGenerator.generateOrderNo1());

        orderInfo.setOrderStatus(0L);
        orderInfo.setCreateTime(DateUtils.getNowDate());
//        orderInfo.setMemberId(SecurityUtils.getAppUserId());

        orderInfo.setChName(reqVO.getChName());
        orderInfo.setChIdNo(reqVO.getChIdNo());
        orderInfo.setChCardNo(reqVO.getChCardNo());
        orderInfo.setChMobile(reqVO.getChMobile());
        orderInfo.setProtocolNo(reqVO.getProtocolNo());
        orderInfo.setPayIp(IpUtils.getIpAddr());
        orderInfo.setRemark(reqVO.getRemark());
        orderInfo.setPayChannel(reqVO.getPayChannel());
        orderInfo.setTotalPrice(orderDetails.stream().map(DoorOrderDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
        //
        easyEntityQuery.insertable(orderInfo).executeRows(true);
        //插入明细
        for (DoorOrderDetail orderDetail : orderDetails) {
            orderDetail.setOrderId(orderInfo.getId());
            easyEntityQuery.insertable(orderDetail).executeRows(true);
        }
        return orderInfo;
    }

    public void refundCallBack(String refundOrderNo) {
        DoorOrder orderInfo = easyEntityQuery.queryable(DoorOrder.class).where(d -> d.refundNo().eq(refundOrderNo)).firstOrNull();
        if (ObjectUtil.isNotNull(orderInfo) && 2L == orderInfo.getOrderStatus()) { // 只有已支付的订单才能退款
            orderInfo.setRefundTime(DateUtils.getNowDate());
            orderInfo.setOrderStatus(3L);
            //orderInfo.setTradeNo(tradeNo);
            easyEntityQuery.updatable(orderInfo).executeRows();
            //运维的话更新余额和到期时间
            if (1L == orderInfo.getType()) {
                List<DoorOrderDetail> orderDetails = easyEntityQuery.queryable(DoorOrderDetail.class).where(d -> d.orderId().eq(orderInfo.getId())).toList();
                for (DoorOrderDetail doorOrderDetail : orderDetails) {
                    DoorDeptPrice doorDeptPrice = easyEntityQuery.queryable(DoorDeptPrice.class).where(d -> d.deptId().eq(doorOrderDetail.getStreet())).firstOrNull();

                    if (doorOrderDetail.getType() == 1L||doorOrderDetail.getType() == 4L) {
                        DoorHouse doorHouse = easyEntityQuery.queryable(DoorHouse.class).where(d -> d.id().eq(doorOrderDetail.getHouseId())).firstOrNull();
                        doorHouse.setUpdateTime(DateUtils.getNowDate());
                        BigDecimal totalPrice = doorOrderDetail.getTotalPrice();
                        //计算退款金额（包含赠送的部分）
                        int year = (int) (doorOrderDetail.getBuyCount() / 12);
                        if (year > 0) {
                            //判断是否配置了赠送，退款时也要扣除赠送的金额
                            if (ObjectUtil.isNotNull(doorDeptPrice) && doorDeptPrice.getGiftMonthOfByOneYear() > 0) {
                                BigDecimal giftMonthOfByOneYear = BigDecimal.valueOf(doorDeptPrice.getGiftMonthOfByOneYear()).multiply(BigDecimal.valueOf(year));
                                BigDecimal multiply = doorHouse.getMonthPrice().multiply(giftMonthOfByOneYear);
                                doorHouse.setRemark(DateUtil.now() + ",退款扣除赠送" + multiply + "元");
                                totalPrice = totalPrice.add(multiply);
                            }
                        }
                        //减少余额
                        doorHouse.setBalance(doorHouse.getBalance().subtract(totalPrice));
                        //根据新的余额重新计算到期时间
                        doorHouse.setEndDate(HouseUtil.calculateEndDateFromBaseDate(doorHouse.getBalance(), doorHouse.getMonthPrice()));
                        doorHouse.setStartDate(new DateTime(LocalDate.of(DateUtil.thisYear(), DateUtil.thisMonth()+1, 1)));

                        easyEntityQuery.updatable(doorHouse).executeRows();
                    }
                }
            }
        }
    }

    /**
     * 从安装价格JSON数组中根据名称查找对应的价格
     *
     * @param installPriceJson 价格JSON字符串，格式：[{name,price}]
     * @param installPriceName 价格名称
     * @return 对应的价格，如果未找到则返回null
     */
    private BigDecimal findPriceByName(String installPriceJson, String installPriceName) {
        if (StrUtil.isEmpty(installPriceJson) || StrUtil.isEmpty(installPriceName)) {
            return null;
        }
        
        try {
            JSONArray priceArray = JSONArray.parseArray(installPriceJson);
            for (Object item : priceArray) {
                JSONObject priceItem = (JSONObject) item;
                String name = priceItem.getString("name");
                if (installPriceName.equals(name)) {
                    return priceItem.getBigDecimal("price");
                }
            }
        } catch (Exception e) {
            log.error("解析安装价格JSON失败：{}", installPriceJson, e);
        }
        
        return null;
    }
}
